Importation des librairies¶

In [70]:
import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import plotly.express as px
import numpy as np
import plotly.io as pio
import plotly

Importation des données¶

In [47]:
df = pd.read_csv('formatted_data.csv')

Préparations des données¶

In [48]:
df = df[df['fiscYear'].apply(lambda x : x >= 2014)]
df = df[['firstName', 'lastName', 'city', 'postalCode', 'entity', 'amount', 'fiscYear']]
dfMP = df[df['entity'].isin(['C.A.Q.- É.F.L.', 'P.C.Q./C.P.Q.','P.L.Q./Q.L.P.', 'P.Q.', 'Q.S.'])]
dfPCQ = df[df['entity'] == 'P.C.Q./C.P.Q.']


# Une personne unique s'identifie par son prenom, nom, ville et code postal
idPerson = ['firstName', 'lastName', 'city', 'postalCode']

#trouvons le parti pour lequel une personne a donnée le plus de fois dans une année et ce, pour chaque année
dfHistPivot = dfMP.pivot_table(index=idPerson, columns='fiscYear', values='entity',aggfunc=lambda x: x.mode().iat[0])

src = dfHistPivot.apply(lambda x : x.dropna().iloc[0], axis=1)
src.name = 'source'
dst = dfHistPivot.apply(lambda x : x.dropna().iloc[-1], axis=1)
dst.name = 'destination'

dfHistPivot['src'] = src
dfHistPivot['dst'] = dst
dfHistPivot['changed'] = src != dst
changedSeries = dfHistPivot[dfHistPivot['changed'] == True].groupby(['dst', 'src']).count()['changed']
changedSeries.name = 'nombre'
In [49]:
dfMP = df[df['entity'].isin(['C.A.Q.- É.F.L.', 'P.C.Q./C.P.Q.','P.L.Q./Q.L.P.', 'P.Q.', 'Q.S.'])]
dfPCQ = df[df['entity'] == 'P.C.Q./C.P.Q.']

sumDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='sum')
nbrDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='count')
meanDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc='mean')
modeDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc=pd.Series.mode)

pivotDonsYearMP = pd.pivot_table(dfMP, index=['entity', 'fiscYear'], values=['amount'], aggfunc=['count', 'sum', 'mean'])

Méthodologie¶

Source des données¶

Les données proviennent du site d'élection Québec. Elles ont été extraitent grâce à un code développer pour ce projet répertoire Github.

Descriptions des données¶

La source de données permet d'obtenir de l'information sur tous les donateurs depuis l'années 2000. Toutefois, nous avons accès au code postal et à la ville pour tous les donateurs depuis 2013 exclusivement. Pour cette raison, nous avons limité notre analyse de 2014 au 17 mars 2022. Une dernière mise à jour des données sera faite avant la publication.

Pour chaque dons, nous avons accès aux informations suivantes :

firstName lastName amount nbrPayment entity fiscYear postalCode city
Émilie A Lachance 100.0 1 P.L.Q./Q.L.P. 2016 H2S2C5 Montréal
Félix A-Papineau 100.0 1 P.L.Q./Q.L.P. 2015 J0W1C0 Ferme-neuve
Miriam Aaron 100.0 1 P.L.Q./Q.L.P. 2013 H3G1L2 Montréal
Miriam Aaron 50.0 1 P.L.Q./Q.L.P. 2014 H3G1L2 Montréal
... ... ... ... ..... ... ... ...

Résultats¶

1 - Combien de donateurs uniques¶

In [50]:
dfHistPivot.shape[0]
Out[50]:
120810

Il y a 120810 donateurs distincts entre 2014 et 2022

Est-ce qu'il s'agit de nouveau donateur?¶

In [51]:
dst.value_counts()
Out[51]:
P.Q.              38284
P.L.Q./Q.L.P.     29723
C.A.Q.- É.F.L.    24288
Q.S.              15817
P.C.Q./C.P.Q.     12698
Name: destination, dtype: int64
In [52]:
diff = dst.value_counts()-src.value_counts()
donateurs_distincts_PCQ = dst.value_counts().loc['P.C.Q./C.P.Q.']
donateurs_distincts_PCQ
Out[52]:
12698

Le don le plus récent de 12698 donateurs distincts était pour le PCQ.

In [53]:
diff
Out[53]:
P.Q.              -894
P.L.Q./Q.L.P.    -1699
C.A.Q.- É.F.L.    2224
Q.S.                39
P.C.Q./C.P.Q.      330
dtype: int64
In [54]:
autre_entite = diff.loc['P.C.Q./C.P.Q.']
autre_entite
Out[54]:
330

De ces 12698 donateurs, seulement 330 donnaient précédemment pour un autre parti avant le PCQ

In [55]:
nouveau_donateur = dst.value_counts().loc['P.C.Q./C.P.Q.'] - diff.loc['P.C.Q./C.P.Q.']
pourc_nouveau = (donateurs_distincts_PCQ-autre_entite)/donateurs_distincts_PCQ *100
In [56]:
pourc_nouveau
Out[56]:
97.40116553787999

97.4% des donateurs du PCQ n'ont jamais donnée pour d'autre parti entre 2014 et 2022

À quel parti donnait ceux dont le don le plus ancien n'était pas pour le PCQ et que le don le plus récent est pour le PCQ?¶

firstName lastName city postalCode 2014.0 2015.0 2016.0 2017.0 2018.0 2019.0 2020.0 2021.0 2022.0
Alain Beaulieu Lefebvre J0H 2C0 P.C.Q./C.P.Q.
Alain Mattard Montréal H1R 3A3 P.C.Q./C.P.Q. P.C.Q./C.P.Q. P.C.Q./C.P.Q.
Alain Rochon Cayamant J0X 1Y0 Q.S. P.C.Q./C.P.Q. P.C.Q./C.P.Q.
Alan Wallis Saint-denis-de-brompton J0B 2P0 C.A.Q.- É.F.L. C.A.Q.- É.F.L. C.A.Q.- É.F.L. C.A.Q.- É.F.L. C.A.Q.- É.F.L. P.C.Q./C.P.Q.

Dans cet exemple, les deux premiers donateurs seraient des nouveaux donateurs, car ils ont toujours donné pour le PCQ ou donné qu'une seule fois.

Les deux derniers seraient des donateurs qui ont changé d'allégence, car leur don le plus ancien est différent du plus récent.

In [77]:
plotly.offline.init_notebook_mode()
figPCQ = go.Figure(data=[go.Sankey(
    node = dict(
      pad = 15,
      thickness = 20,
      line = dict(color = "black", width = 0.5),
      label = ["CAQ", "PCQ", "PLQ", "PQ", "QS"],
      color = ["cyan", "purple", "red", "blue", "orange"]
    ),
    link = dict(
      source = [0,2,3,4], # indices correspond to labels, eg A1, A2, A1, B1, ...
      target = [1,1,1,1],
      value = changedSeries.values[4:8],

  ))])

figPCQ.update_layout(title_text="Changement d'allégence vers le PCQ", font_size=30)
figPCQ.show()

2 - Où se trouve les donateurs du PCQ?¶

In [75]:
plotly.offline.init_notebook_mode()

px.bar(dfPCQ.groupby('city').sum()['amount'].sort_values(ascending=False)[:10].reset_index(),
    y='city',
    x='amount',
    labels={'amount':'Somme de dons ($)',
           'city':'Ville'},
    title="Top 10 par somme de dons pour les villes du Québec")
        

3 - Comment se compare la performance de collecte de dons du PCQ par rapport aux autres partis?¶

In [72]:
plotly.offline.init_notebook_mode()
f2 = px.bar(nbrDonsYearMP.reset_index(),
            x='fiscYear',
            y='amount',
            color='entity',
            barmode='group',
            title="Nombre de dons amassé par années pour chaque parti",
            labels={'fiscYear':"Année Fiscale",
                    'amount' : "Nombre de dons"}
    )
f2.show()
In [74]:
plotly.offline.init_notebook_mode()
f3 = px.bar(meanDonsYearMP.reset_index(),
            x='fiscYear',
            y='amount',
            color='entity',
            barmode='group',
            title="Valeur moyenne de chaque dons effectué a un parti politique par année",
            labels={'fiscYear':"Année Fiscale",
                    'amount' : "Valeur moyenne d'un don($)"}
    )
f3.show()
In [ ]: